Bash Filter Array With Another Array
Single Line String to Array
filter elements from one array based on another array using associative arrays (available in Bash 4.0 and above). Associative arrays allow you to use strings as keys, making the membership test more efficient.
Here's how you can do it:
#!/bin/bash
IFS=' ' read -r -a COLOR_ARRAY <<< "red yellow blue green yellow white black"
REMOVABLE_WORDS=("yellow" "white" "black")
echo "COLOR_ARRAY Array: ${COLOR_ARRAY[*]}"
# Declare an associative array
declare -A REMOVABLE_DICT
# Populate the associative array with removable words
for word in "${REMOVABLE_WORDS[@]}"
do
REMOVABLE_DICT["$word"]=1
done
# Initialize a new array for filtered elements
NEW_ARRAY=()
# Filter the COLOR_ARRAY based on the REMOVABLE_DICT
for element in "${COLOR_ARRAY[@]}"
do
if [[ -z ${REMOVABLE_DICT["$element"]} ]]; then
NEW_ARRAY+=("$element")
fi
done
# Print the filtered array
echo "Filtered Array: ${NEW_ARRAY[*]}"
This script does the following:
- Reads the initial array
VERSION_ARRAY
. - Initializes an associative array
REMOVABLE_DICT
and populates it with the words to be removed. - Initializes an empty array
NEW_ARRAY
to store the filtered elements. - Iterates over each element in
VERSION_ARRAY
. - Checks if the element is not in the
REMOVABLE_DICT
. - If the element is not in
REMOVABLE_DICT
, it adds the element toNEW_ARRAY
. - Finally, it prints the filtered array.
Using associative arrays provides a cleaner and more efficient way to check for membership compared to using regular arrays.
Multi-Line String to Array
Sometimes the input is a multi-line string where each line item is one element in the array. use the readarray
to parse it correctly
#!/bin/bash
MULTILINE_STRING="hero1
hero2
badguy1
hero3
badguy2"
readarray -t original_array <<< "$MULTILINE_STRING"
# Words to remove
words_to_remove=("badguy1" "badguy2")
# Declare an associative array (dictionary) for words to remove
declare -A remove_dict
for word in "${words_to_remove[@]}"
do
remove_dict["$word"]=1
done
# Filter the original array
filtered_array=()
for word in "${original_array[@]}"
do
if [[ -z "${remove_dict["$word"]}" ]]
then
filtered_array+=("$word")
fi
done
# Output the filtered array
echo "Filtered Array: ${filtered_array[@]}"